"""
coding = 'utf-8'
writingtime:2022-7-25
author: 赵维骏
reference:
doi:
examiner:
"""
from math import *


class weber():
    def __init__(self, data_list, weight_list, q, y, x):
        """
        function: 初始化各类值
        """
        self.data_list = data_list
        self.weight_list = weight_list
        self.q = q
        self.y = y
        self.x = x
        pass

    def add(self, a1, a2, q=2, w=2):
        """
        function: weber算子的基础和函数
        return: 计算结果 模糊集区间 例:([x, y], [x, y])
        """
        if q <= 0:
            q = self.q
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        u1 = (pow(u_1_f, q) + pow(u_2_f, q) - (w / (1 + w)) * pow(u_1_f, q) * pow(u_2_f, q)) ** (1 / q)
        u2 = (pow(u_1_r, q) + pow(u_2_r, q) - (w / (1 + w)) * pow(u_1_r, q) * pow(u_2_r, q)) ** (1 / q)
        v1 = ((pow(v_1_f, q) + pow(v_2_f, q) + w * pow(v_1_f, q) * pow(v_2_f, q) - 1) / (1 + w)) ** (1 / q)
        v2 = ((pow(v_1_r, q) + pow(v_2_r, q) + w * pow(v_1_r, q) * pow(v_2_r, q) - 1) / (1 + w)) ** (1 / q)
        print(u1,'\n',u2,'\n',v1,'\n',v2)
        return ([min(1, u1), min(1, u2)], [max(0, v1), max(0, v2)])

    def multi(self, a1, a2, q, w=2):
        """
        function: weber算子基础积函数
        return: 计算结果 模糊集区间 例:([x, y], [x, y])
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        u1 = ((pow(u_1_f, q) + pow(u_2_f, q) + w * pow(u_1_f, q) * pow(u_2_f, q) - 1) / (1 + w)) ** (1 / q)
        u2 = ((pow(u_1_r, q) + pow(u_2_r, q) + w * pow(u_1_r, q) * pow(u_2_r, q) - 1) / (1 + w)) ** (1 / q)
        v1 = (pow(v_1_f, q) + pow(v_2_f, q) - (w / (1 + w)) * pow(v_1_f, q) * pow(v_2_f, q)) ** (1 / q)
        v2 = (pow(v_1_r, q) + pow(v_2_r, q) - (w / (1 + w)) * pow(v_1_r, q) * pow(v_2_r, q)) ** (1 / q)
        return ([max(0, u1), max(0, u2)], [min(1, v1), min(1, v2)])

    def kmulti(self, a1, q, w=2, l=2):
        """
        function: weber算子数乘函数
        return: 计算结果 模糊集区间 例:([x, y], [x, y])
        利用基础和函数将两个a1相加, 看结果的2落在什么位置, 再将2换成参数l
        """
        u_f, u_r, v_f, v_r = *a1[0], *a1[1]
        if q <= 0:
            q = self.q
        u1 = (l * pow(u_f, q) - (w / (1 + w)) * pow(u_f, l * q)) ** (1 / q)
        u2 = (l * pow(u_r, q) - (w / (1 + w)) * pow(u_r, l * q)) ** (1 / q)
        v1 = ((l * pow(v_f, q) + w * pow(v_f, l * q) - 1) / (1 + w)) ** (1 / q)
        v2 = ((l * pow(v_r, q) + w * pow(v_r, l * q) - 1) / (1 + w)) ** (1 / q)
        return ([min(1, u1), min(1, u2)], [max(0, v1), max(0, v2)])

    def pow(self, a1, q, w=2, l=2):
        """
       function: weber算子乘方函数
       return :计算结果 模糊集区间 例:([x, y], [x, y])
       利用基础积函数将两个a1相乘, 看结果的2落在什么位置, 再将2换成参数l
        """
        u_f, u_r, v_f, v_r = *a1[0], *a1[1]
        if q <= 0:
            q = self.q
        u1 = ((l * pow(u_f, q) + w * pow(u_f, l * q) - 1) / (1 + w)) ** (1 / q)
        u2 = ((l * pow(u_r, q) + w * pow(u_r, l * q) - 1) / (1 + w)) ** (1 / q)
        v1 = (l * pow(v_f, q) - (w / (1 + w)) * pow(u_f, l * q)) ** (1 / q)
        v2 = (l * pow(v_r, q) - (w / (1 + w)) * pow(u_r, l * q)) ** (1 / q)
        return ([max(0, u1), max(0, u2)], [min(1, v1), min(1, v2)])

    def get_pi(self, a, *waste1, **waste2):
        pi_f = pow(1 - pow(a[0][1], self.q) - pow(a[1][1], self.q), 1 / self.q)
        pi_r = pow(1 - pow(a[0][0], self.q) - pow(a[1][0], self.q), 1 / self.q)
        return ([pi_f, pi_r])

    def get_d(self, a1, a2, *waste1, **waste2):
        u_1_f, u_1_r, v_1_f, v_1_r, pi_1_f, pi_1_r = *a1[0], *a1[1], *self.get_pi(a1)
        u_2_f, u_2_r, v_2_f, v_2_r, pi_2_f, pi_2_r = *a2[0], *a2[1], *self.get_pi(a2)
        part_u = fabs(u_1_f ** self.q - u_2_f ** self.q) + fabs(u_1_r ** self.q - u_2_r ** self.q)
        part_v = fabs(v_1_f ** self.q - v_2_f ** self.q) + fabs(v_1_r ** self.q - v_2_r ** self.q)
        part_r = fabs(pi_1_f ** self.q - pi_2_f ** self.q) + fabs(pi_1_r ** self.q - pi_2_r ** self.q)
        d_value = 1 / 4 * (part_r + part_v + part_u)
        return d_value

    def get_sup(self, a1, a2):
        return 1 - self.get_d(a1, a2)

    def get_ta(self, i_a, *waste1, **waste2):
        ta = 0
        for j in range(len(self.data_list)):
            if i_a != j:
                ta += self.get_sup(self.data_list[i_a], self.data_list[j]) * self.weight_list[j]
        return ta

    def getResult(self, *waste1, **waste2):  # weber和Hamy Mean融合
        data = self.data_list
        n = len(data)
        a = self.y
        b = self.x
        a_result = self.multi(self.pow(data[0], a), self.pow(data[0], b))
        for i in range(1, n):
            a_temp = self.multi(self.pow(data[0], a), self.pow(data[i], b))
            a_result = self.add(a_temp, a_result)

        for i in range(1, n):
            a_i = self.multi(self.pow(data[i], a), self.pow(data[i], b))
            for j in range(i + 1, n):
                a_j = self.multi(self.pow(data[i], a), self.pow(data[j], b))
                a_i = self.add(a_j, a_i)
            a_result = self.add(a_result, a_i)
        a_result = self.kmulti(a_result, (2 / (n + 1)))
        a_result = self.pow(a_result, 1 / (a + b))
        return a_result

    def getResult2(self, *waste1, **waste2):  # weber和PA融合
        ta_add = 0  # 记录 T(ai)+1 累加部分
        print(self.data_list)
        print(self.weight_list)
        for i_a in range(len(self.data_list)):
            ta_add += (1 + self.get_ta(i_a)) * self.weight_list[i_a]

        # 根据原始公式调用运算符号进行

        a_result = self.pow(self.data_list[0], ((1 + self.get_ta(0)) * self.weight_list[0]) / ta_add)
        for i_a in range(1, len(self.data_list)):
            a1 = a_result
            a2 = self.pow(self.data_list[i_a], ((1 + self.get_ta(i_a)) * self.weight_list[i_a]) / ta_add)
            a_result = self.multi(a1, a2)
        return a_result


if __name__ == "__main__":
    data = [([0.31, 0.24], [0.73, 0.72]), ([0.8, 0.52], [0.73, 0.15]), ([0.91, 0.49], [0.42, 0.47]),
            ([0.95, 0.06], [0.19, 0.1])]
    weight_list = [0.1, 0.2, 0.3, 0.1, 0.3]
    data2 = ([0.2, 0.53], [0.51, 0.67])
    # weight_list = [([0.97, 0.12], [0.12, 0.05])]
    result = weber(data, weight_list, 2, 2, 2)
    print(result.add(data2, data2, 2))  # 测试a1+a1是否等于2*a1
    print(result.kmulti(data2, 2))  # 测试a1+a1是否等于2*a1
    # print(result.multi(data2, data2, 0.5))       #测试a1*a1是否等于a1平方
    # print(result.pow(data2, 0.5))                    #测试a1*a1是否等于a1平方, 以上结果均正确
    # print(result.getResult(data, weight_list))
